home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #9 / Amiga Plus CD - 2004 - No. 09.iso / amigaplus / tools / dev_libs / feelin040718 / demos / lines.c < prev    next >
C/C++ Source or Header  |  2004-08-03  |  14KB  |  502 lines

  1. ;/*
  2.    SC Lines.c
  3.    QUIT
  4.    _________________________________________________________________________
  5.  
  6.    Class2 Demo © 2000-2003 by Olivier LAVIALE <HaploLaMain@aol.com>
  7.  
  8.    This example illustrate how to writte a  custom  class  using  a  methods
  9.    table instead of a dispatcher. This class doesn't use Dynamic IDs.
  10. */
  11.  
  12. ///Header
  13.  
  14. #include <libraries/feelin.h>
  15. #include <proto/exec.h>
  16. #include <proto/dos.h>
  17. #include <proto/graphics.h>
  18. #include <proto/utility.h>
  19. #include <proto/feelin.h>
  20.  
  21. struct FeelinBase                  *FeelinBase;
  22. #define GfxBase                     FeelinBase -> Graphics
  23. #define UtilityBase                 FeelinBase -> Utility
  24.  
  25. /*
  26.    Using static IDs is not a good idea, but this is just  a  demo  and  I'm
  27.    lazy ;-)
  28. */
  29.  
  30. #define FM_Lines_Update             (FCCM_BASE + 0)
  31.  
  32. #define FA_Lines_Cycle              (FCCA_BASE + 0)
  33. #define FA_Lines_Trail              (FCCA_BASE + 1)
  34. #define FA_Lines_Micro              (FCCA_BASE + 2)
  35.  
  36. struct LocalObjectData
  37. {
  38.    FAreaData                       *AreaData;
  39.  
  40.    struct FeelinSignalHandler       SignalHandler;
  41.    WORD                             x[2],y[2];
  42.    WORD                             xd[2],yd[2];
  43.    APTR                             ox[2],oy[2];
  44.    ULONG                            j;
  45.    ULONG                            Pen;        // FV_Pen_Xxx
  46.    UBYTE                            Cycle;
  47.    UBYTE                            CycleDone;
  48.    BYTE                             CycleWay;
  49.    UBYTE                            Line;       // Line to draw (or beeing drawn)
  50.    BYTE                             k;
  51.    UBYTE                            Trail;
  52.    APTR                             TrailData;
  53. };
  54.  
  55. long rand(void);
  56.  
  57. #define MyLine                                  F_NewObj(Class -> Name,TAG_DONE)
  58.  
  59. //+
  60.  
  61. ///ModifyTrail
  62. APTR ModifyTrail(struct FeelinClass *Class,FObject Obj,UBYTE Trail)
  63. {
  64.    struct LocalObjectData *LOD = F_LOD(Class,Obj);
  65.  
  66.    LOD -> Trail = 0;
  67.  
  68.    if (LOD -> TrailData)
  69.    {
  70.       LOD -> ox[0] = 0; LOD -> ox[1] = 0; // Reset coordinates
  71.       LOD -> oy[0] = 0; LOD -> oy[1] = 0; // Reset coordinates
  72.  
  73.       F_Dispose(LOD -> TrailData);
  74.    }
  75.  
  76.    if (LOD -> TrailData = F_New(sizeof (WORD) * 4 * Trail))
  77.    {
  78.       LOD -> ox[0] = LOD -> TrailData;
  79.       LOD -> ox[1] = (APTR)((ULONG)(LOD -> ox[0]) + sizeof (WORD) * Trail);
  80.       LOD -> oy[0] = (APTR)((ULONG)(LOD -> ox[1]) + sizeof (WORD) * Trail);
  81.       LOD -> oy[1] = (APTR)((ULONG)(LOD -> oy[0]) + sizeof (WORD) * Trail);
  82.    }
  83.  
  84.    LOD -> Trail = Trail;
  85.  
  86.    return LOD -> TrailData;
  87. }
  88. //+
  89.  
  90. /// mNew
  91. F_METHOD(APTR,mNew)
  92. {
  93.    struct LocalObjectData *LOD = F_LOD(Class,Obj);
  94.  
  95.    LOD -> AreaData = (FAreaData *) F_Get(Obj,FA_AreaData);
  96.  
  97.    LOD -> Cycle                     = 1;
  98.    LOD -> Trail                     = 8;
  99.    LOD -> SignalHandler.Object      = Obj;
  100.    LOD -> SignalHandler.Method      = FM_Lines_Update;
  101.    LOD -> SignalHandler.Flags       = FF_SignalHandler_Timer;
  102.    LOD -> SignalHandler.fsh_Secs    = 0;
  103.    LOD -> SignalHandler.fsh_Micros  = 10000;
  104.  
  105.    if (F_SuperDo(Class,Obj,Method,
  106.  
  107.       FA_ChainToCycle,        FALSE,
  108.       FA_Back,                FI_Dark,
  109.       FA_Frame,              "FP_Gauge_Frame",
  110.       FA_Lines_Cycle,         8,
  111.       FA_Lines_Trail,         16,
  112.  
  113.       TAG_MORE, Msg))
  114.    {
  115.       if (!LOD -> TrailData) ModifyTrail(Class,Obj,LOD -> Trail);
  116.  
  117.       if (LOD -> TrailData)
  118.       {
  119.          return Obj;
  120.       }
  121.    }
  122.    return NULL;
  123. }
  124. //+
  125. ///mDispose
  126. F_METHOD(void,mDispose)
  127. {
  128.    struct LocalObjectData *LOD = F_LOD(Class,Obj);
  129.  
  130.    if (LOD -> TrailData)
  131.    {
  132.       F_Dispose(LOD -> TrailData); LOD -> TrailData = NULL;
  133.    }
  134.  
  135.    F_SUPERDO();
  136. }
  137. //+
  138. ///mSet
  139. F_METHOD(void,mSet)
  140. {
  141.    struct LocalObjectData *LOD  = F_LOD(Class,Obj);
  142.    struct TagItem         *Tags = Msg,
  143.                           *item;
  144.  
  145.    while  (item = NextTagItem(&Tags))
  146.    switch (item -> ti_Tag)
  147.    {
  148.       case FA_Lines_Cycle:
  149.       {
  150.          LOD -> Cycle = item -> ti_Data;
  151.          LOD -> Pen = (LOD -> Cycle) ? FV_Pen_Shine : FV_Pen_Highlight;
  152.       }
  153.       break;
  154.  
  155.       case FA_Lines_Trail:
  156.       {
  157.          if (FF_Area_CanDraw & _flags)
  158.          {
  159.             F_Do(Obj,FM_Hide);
  160.  
  161.             ModifyTrail(Class,Obj,item -> ti_Data);
  162.  
  163.             F_Do(Obj,FM_Show);
  164.  
  165.             F_Draw(Obj,FF_Draw_Object);
  166.          }
  167.          else
  168.          {
  169.             ModifyTrail(Class,Obj,item -> ti_Data);
  170.          }
  171.       }
  172.       break;
  173.  
  174.       case FA_Lines_Micro:
  175.       {
  176.          if (FF_Area_CanDraw & _flags)
  177.          {
  178.             F_Do(_app,FM_Application_RemSignalHandler,&LOD -> SignalHandler);
  179.             LOD -> SignalHandler.fsh_Micros = item -> ti_Data;
  180.             F_Do(_app,FM_Application_AddSignalHandler,&LOD -> SignalHandler);
  181.          }
  182.          else
  183.          {
  184.             LOD -> SignalHandler.fsh_Micros = item -> ti_Data;
  185.          }
  186.       }
  187.       break;
  188.    }
  189.  
  190.    F_SUPERDO();
  191. }
  192. //+
  193. /// mShow
  194. F_METHOD(LONG,mShow)
  195. {
  196.    struct LocalObjectData *LOD = F_LOD(Class,Obj);
  197.  
  198. /*
  199.    It's better to add signal handlers in the  FM_Show  method  because  the
  200.    object  may  be  hidden  at  any time and even if it won't be able to be
  201.    drawn it's a waste of time (CPU time) to leave it active.
  202. */
  203.  
  204.    if (F_SUPERDO())
  205.    {
  206.       F_Do(_app,FM_Application_AddSignalHandler,&LOD -> SignalHandler);
  207.  
  208.       return TRUE;
  209.    }
  210.    return FALSE;
  211. }
  212. //+
  213. /// mHide
  214. F_METHOD(void,mHide)
  215. {
  216.    struct LocalObjectData *LOD = F_LOD(Class,Obj);
  217.  
  218.    if (FF_Area_CanShow & _flags)
  219.    {
  220.       F_Do(_app,FM_Application_RemSignalHandler,&LOD -> SignalHandler);
  221.    }
  222.    F_SUPERDO();
  223. }
  224. //+
  225. /// mAskMinMax
  226. /*
  227. AskMinMax method will be called before the  window  is  opened  and  before
  228. layout  takes place. We need to tell Feelin the minimum and maximum size of
  229. our object. Note that we indeed need to *add* these values,  not  just  set
  230. them !
  231. */
  232. F_METHOD(ULONG,mAskMinMax)
  233. {
  234.    struct LocalObjectData *LOD = F_LOD(Class,Obj);
  235.  
  236.    _minw += 30;
  237.    _minh += 30;
  238.  
  239. /*
  240. Now call our superclass. FC_Area will handle everything,  taking  care  of
  241. FA_FixedXxx, FA_MinXxx and FA_MaxXxx.
  242. */
  243.  
  244.    return F_SUPERDO();
  245. }
  246. //+
  247. /// mDraw
  248. /*
  249. Draw method is called whenever  Feelin  feels  (obviously  ;-))  we  should
  250. render our object. This usually happens after layout is finished. Note: You
  251. may  only  render  within  the  rectangle  _mx(Obj),  _my(Obj),  _mx2(Obj),
  252. _my2(Obj).
  253. */
  254. F_METHODM(void,mDraw,FS_Draw)
  255. {
  256.    struct LocalObjectData *LOD = F_LOD(Class,Obj);
  257.    struct RastPort        *rp  = _rp;
  258.    register short i;
  259.  
  260.    WORD *ox;
  261.    WORD *oy;
  262.  
  263. /*
  264. let our superclass draw itself first, Area class would e.g. draw the  frame
  265. and clear the whole region. What it does exactly depends on flags.
  266. */
  267.  
  268.    if (FF_Draw_Object & Msg -> Flags)
  269.    {
  270.       /* Reset values */
  271.  
  272.       for (i = 0 ; i < 2 ; i++)
  273.       {
  274.          LOD ->  x[i] = _mx + (rand() % _mw); if (LOD -> x[i] < _mx) LOD -> x[i] = _mx; else if (LOD -> x[i] > _mx2) LOD -> x[i] = _mx2;
  275.          LOD ->  y[i] = _my + (rand() % _mh); if (LOD -> y[i] < _my) LOD -> y[i] = _my; else if (LOD -> y[i] > _my2) LOD -> y[i] = _my2;
  276.          LOD -> xd[i] = rand() % 10 + 1;
  277.          LOD -> yd[i] = rand() % 10 + 1;
  278.       }
  279.  
  280.       LOD -> Pen        = (LOD -> Cycle) ? FV_Pen_Shine : FV_Pen_Highlight;
  281.       LOD -> j          = 0;
  282.       LOD -> CycleWay   = 1;
  283.       LOD -> CycleDone  = 0;
  284.       LOD -> Line       = 0;
  285.  
  286.       F_SUPERDO();
  287.    }
  288.  
  289.    if (!LOD -> TrailData) return;
  290.  
  291.    if (LOD -> j >= LOD -> Trail - 1)
  292.    {
  293.       i = (LOD -> Line >= LOD -> Trail - 1) ? 0 : LOD -> Line + 1;
  294.  
  295.       _FPen(FV_Pen_Dark);
  296.       ox = LOD -> ox[0]; oy = LOD -> oy[0]; _Move(ox[i],oy[i]);
  297.       ox = LOD -> ox[1]; oy = LOD -> oy[1]; _Draw(ox[i],oy[i]);
  298.    }
  299.  
  300.    _FPen(LOD -> Pen);
  301.    _Move(LOD -> x[0],LOD -> y[0]);
  302.    _Draw(LOD -> x[1],LOD -> y[1]);
  303.  
  304.    if (LOD -> Cycle && ++LOD -> CycleDone >= LOD -> Cycle)
  305.    {
  306.       LOD -> CycleDone = 0;
  307.  
  308.       if (LOD -> CycleWay > 0)
  309.       {
  310.          if (LOD -> Pen + 1 >= FV_Pen_Dark) LOD -> CycleWay = -1;
  311.       }
  312.       else
  313.       {
  314.          if (LOD -> Pen - 1 <= FV_Pen_Shine) LOD -> CycleWay = 1;
  315.       }
  316.  
  317.       LOD -> Pen += LOD -> CycleWay;
  318.    }
  319.  
  320.    for (i = 0 ; i < 2 ; i++)
  321.    {
  322.       ox = LOD -> ox[i]; ox[LOD -> Line] = LOD -> x[i];
  323.       oy = LOD -> oy[i]; oy[LOD -> Line] = LOD -> y[i];
  324.  
  325.       LOD -> x[i] += LOD -> xd[i];
  326.       LOD -> y[i] += LOD -> yd[i];
  327.  
  328.       if (LOD -> x[i] < _mx)
  329.       {
  330.          LOD -> xd[i] = -LOD -> xd[i]; LOD -> x[i] = _mx;
  331.       }
  332.       else if (LOD -> x[i] > _mx2)
  333.       {
  334.          LOD -> xd[i] = -LOD -> xd[i]; LOD -> x[i] = _mx2;
  335.       }
  336.  
  337.       if (LOD -> y[i] < _my)
  338.       {
  339.          LOD -> yd[i] = -LOD -> yd[i]; LOD -> y[i] = _my;
  340.       }
  341.       else if (LOD -> y[i] > _my2)
  342.       {
  343.          LOD -> yd[i] = -LOD -> yd[i]; LOD -> y[i] = _my2;
  344.       }
  345.  
  346.       /* Twisting coordinates */
  347.  
  348.       if (((rand() >> 5) & 127) < 2)
  349.       {
  350.          if (LOD -> xd[i] < 1) LOD -> k = TRUE;
  351.          LOD -> xd[i] = (rand() >> 5) & 7;
  352.          if (LOD -> k) LOD -> xd[i] = -LOD -> xd[i];
  353.          LOD -> k = FALSE;
  354.       }
  355.  
  356.       if (((rand() >> 5) & 255) < 50)
  357.       {
  358.           if (LOD -> yd[i] < 1) LOD -> k = TRUE;
  359.           LOD -> yd[i] = (rand() >> 5) & 7;
  360.           if (LOD -> k) LOD -> yd[i] = -LOD -> yd[i];
  361.           LOD -> k = FALSE;
  362.       }
  363.    }
  364.  
  365.    if (++LOD -> Line >= LOD -> Trail) LOD -> Line = 0;
  366.    LOD -> j++;
  367. }
  368. //+
  369. ///mUpdate
  370. F_METHOD(LONG,mUpdate)
  371. {
  372.    F_Draw(Obj,FF_Draw_Update);
  373.    return TRUE; // If we return FALSE the timer event won't be requested again
  374. }
  375. //+
  376.  
  377. ///Main
  378. void main()
  379. {
  380.    APTR app,win,
  381.         grp,gad_ccl,gad_trl,gad_spd;
  382.  
  383.    struct FeelinClass *Class;
  384.  
  385.    static struct FeelinMethodEntry Handlers[] =
  386.    {
  387.       (FMethod) mNew,       NULL, FM_New,
  388.       (FMethod) mDispose,   NULL, FM_Dispose,
  389.       (FMethod) mSet,       NULL, FM_Set,
  390.       (FMethod) mShow,      NULL, FM_Show,
  391.       (FMethod) mHide,      NULL, FM_Hide,
  392.       (FMethod) mAskMinMax, NULL, FM_AskMinMax,
  393.       (FMethod) mDraw,      NULL, FM_Draw,
  394.       (FMethod) mUpdate,    NULL, FM_Lines_Update,
  395.  
  396.       NULL
  397.    };
  398.  
  399.    if (FeelinBase = (APTR) OpenLibrary("feelin.library",FV_VERSION))
  400.    {
  401.  
  402. /*
  403. Create the new custom class with a call to F_CreateClassA().
  404.  
  405. This function returns a struct FeelinClass. You must  use  cc  ->  Name  to
  406. create  instance  of  your  custom  class.  This Name is unique and made by
  407. F_CreateClassA().
  408. */
  409.  
  410.       if (Class = F_CreateClass(FA_Class_Super,          FC_Area,
  411.                                 FA_Class_LODSize,        sizeof (struct LocalObjectData),
  412.                                 FA_Class_MethodsTable,   Handlers,
  413.                                 TAG_DONE))
  414.       {
  415.          app = AppObject,
  416.             FA_Application_Title,        "demo_Lines",
  417.             FA_Application_Version,      "$VER: demo_Lines 1.0 (2003/02/10)",
  418.             FA_Application_Copyright,    "© 2000-2003 Olivier LAVIALE",
  419.             FA_Application_Author,       "Olivier LAVIALE <HaploLaMain@aol.com>",
  420.             FA_Application_Description,  "Tutorial on Client.AddSignalHandler()",
  421.             FA_Application_Base,         "demo_Lines",
  422.  
  423.             Child, win = WindowObject,
  424.                FA_ID,           MAKE_ID('M','A','I','N'),
  425.                FA_Window_Title, "Feelin : Lines",
  426.                FA_Window_Open,   TRUE,
  427.  
  428.                Child, grp = Page,
  429.                   Child, VGroup, FA_Group_Title, "One",
  430.                      Child, MyLine,
  431.  
  432.                      Child, HGroup,
  433.                         FA_Frame,         "FP_Group_Frame",
  434.                         FA_Frame_Title,   "Controls",
  435.                         FA_SetMax,        FV_SetMaxH,
  436.                         FA_ContextHelp,   "Settings made on this page will be reflected\nto all FC_Lines objects",
  437.                         FA_Group_Columns, 2,
  438.  
  439.                         Child, TextObject, FA_Text, "Cycle :",  FA_SetMax,TRUE, DontChain, End,
  440.                         Child, gad_ccl = SliderA, TRUE,0,200,8,
  441.                            FA_ID,          MAKE_ID('C','Y','C','L'),
  442.                            FA_ContextHelp, "Adjust the number of lines to draw\nbefore a color cyling.\n\nSetting this to 0 disable cycling.",
  443.                            End,
  444.  
  445.                         Child, TextObject, FA_Text, "Trail :",  FA_SetMax,TRUE, DontChain, End,
  446.                         Child, gad_trl = SliderA, TRUE,8,100,16,
  447.                            FA_ID,          MAKE_ID('T','R','A','Y'),
  448.                            FA_ContextHelp, "Adjust the number of trailing lines.",
  449.                            End,
  450.  
  451.                         Child, TextObject, FA_Text, "Micros :", FA_SetMax,TRUE, DontChain, End,
  452.                         Child, gad_spd = SliderA, TRUE,5000,100000,10000,
  453.                           "FA_Numeric_Step", 1000,
  454.                            FA_ID,          MAKE_ID('S','P','E','D'),
  455.                            FA_ContextHelp, "Adjust the number of micro seconds\nto wait between each drawing.",
  456.                            End,
  457.                      End,
  458.                   End,
  459.  
  460.                   Child, VGroup, FA_Group_Title, "Four", FA_Group_Rows,2,
  461.                      Child, MyLine, Child, MyLine,
  462.                      Child, MyLine, Child, MyLine,
  463.                   End,
  464.  
  465.                   Child, VGroup, FA_Group_Title, "More", FA_Group_Rows,4,
  466.                      Child, MyLine, Child, MyLine, Child, MyLine, Child, MyLine,
  467.                      Child, MyLine, Child, MyLine, Child, MyLine, Child, MyLine,
  468.                      Child, MyLine, Child, MyLine, Child, MyLine, Child, MyLine,
  469.                      Child, MyLine, Child, MyLine, Child, MyLine, Child, MyLine,
  470.                   End,
  471.                End,
  472.             End,
  473.          End;
  474.  
  475.          if (app)
  476.          {
  477.             F_Do(win,FM_Notify,FA_Window_CloseRequest,TRUE,app,FM_Application_Shutdown,0);
  478.             F_Do(gad_ccl,FM_Notify,"FA_Numeric_Value",FV_Notify_Always,grp,FM_Set,4,FA_Lines_Cycle,FV_Notify_Value,FA_Group_Forward,TRUE);
  479.             F_Do(gad_trl,FM_Notify,"FA_Numeric_Value",FV_Notify_Always,grp,FM_Set,4,FA_Lines_Trail,FV_Notify_Value,FA_Group_Forward,TRUE);
  480.             F_Do(gad_spd,FM_Notify,"FA_Numeric_Value",FV_Notify_Always,grp,FM_Set,4,FA_Lines_Micro,FV_Notify_Value,FA_Group_Forward,TRUE);
  481.  
  482.             F_Do(app,FM_Application_Run);
  483.  
  484.             F_DisposeObj(app);
  485.          }
  486.  
  487.          F_DeleteClass(Class);
  488.       }
  489.       else
  490.       {
  491.          Printf("Unable to create custom class.\n");
  492.       }
  493.  
  494.       CloseLibrary(FeelinBase);
  495.    }
  496.    else
  497.    {
  498.       Printf("Unable to open feelin.library v%ld.\n",FV_VERSION);
  499.    }
  500. }
  501. //+
  502.